<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>constructor属性</title>
</head>
<body>
<h3>constructor 属性</h3>
<p>
    在哪里？ 每个原型对象里面都有个constructor 属性（constructor 构造函数）<br>
    作用：该属性指向该原型对象的构造函数， 简单理解，就是指向我的爸爸，我是有爸爸的孩子
</p>
<h3>使用场景：</h3>
<p>
    如果有多个对象的方法，我们可以给原型对象采取对象形式赋值. <br>
    但是这样就会覆盖构造函数原型对象原来的内容，这样修改后的原型对象 constructor 就不再指向当前构造函数了 <br>
    此时，我们可以在修改后的原型对象中，添加一个 constructor 指向原来的构造函数。
</p>
<hr>
<p>
    总结: constructor属性的作用是什么？ <br>
    指向该原型对象的构造函数
</p>

<script>
    function 构造函数() {
        // 声明 一个函数,先不写东西
    }

    console.log(构造函数.prototype) // 输出的是, 对象. 对象里有一个 constructor属性
    console.log(构造函数.prototype.constructor === 构造函数) // true, 证明 constructor属性, 指向 构造函数.  注意不要加括号,加括号是调用


    // 使用场景
    // 声明一个 构造函数
    function 明星(姓名) {
        this.姓名 = 姓名
    }

    // 原型的写法, 添加 方法  (一般写法)
    // 明星.prototype.唱歌 = function () {
    //     console.log(`${this.姓名} 唱歌`)
    // }
    // 明星.prototype.跳舞 = function () {
    //     console.log(`${this.姓名} 跳舞`)
    // }

    // 可以把方法,在封装在 原型对象里 (这种是对象赋值的形式,但是会覆盖原来的对象内容)
    明星.prototype = {
        // 从新指回创造这个原型对象的 构造函数. 这里一定要加,不然会 覆盖构造函数原型对象原来的内容
        constructor: 明星, // constructor属性,重新指向这个 原型对象的构造函数 (试试修改值,属性的作用是给原型对象找爹,这个爹你可以自己指定,不一定是原来的爹)
        唱歌: function () {
            console.log(`${this.姓名} 唱歌`)
        },
        跳舞: function () {
            console.log(`${this.姓名} 跳舞`)
        },
    }
    // console.log(明星.prototype) // 输出还是,对象. 对象里有2个方法. 但是没有constructor属性了
    console.log(明星.prototype) // 输出还是,对象. 对象里有我们设置的方法. 还有constructor属性,它指向 原型对象的构造函数

    // 实例对象
    const 刘德华 = new 明星('刘德华')
    刘德华.跳舞() // 可以调用方法
</script>

</body>
</html>